package jp.isisredirect.DreamWaverFirst;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.StringTokenizer;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.List;
import java.util.LinkedList;
import java.util.Iterator;
import java.util.Date;
import java.lang.Integer;
import java.lang.Long;

import com.android.future.usb.UsbAccessory;
import com.android.future.usb.UsbManager;

import jp.isisredirect.DreamWaverFirst.R;

import android.app.*;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler; //import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.KeyEvent;
import android.widget.LinearLayout;
import android.widget.TextView;

import android.app.AlertDialog;
import android.content.DialogInterface;

public class DreamWaverFirstActivity extends Activity implements
		OnClickListener, Runnable {
	private static final String TAG = "DreamWaver";

	private static final String ACTION_USB_PERMISSION = "jp.isisredirect.DreamWaverFirst.action.USB_PERMISSION";

	private UsbManager mUsbManager;
	private PendingIntent mPermissionIntent;
	private boolean mPermissionRequestPending;

	UsbAccessory mAccessory;
	ParcelFileDescriptor mFileDescriptor;
	FileInputStream mInputStream;
	FileOutputStream mOutputStream;

	ManualController mManualController;
	AutoController mAutoController;
	SelfcheckController mSelfcheckController;
	PlayerController mPlayerController;

	private Runnable mSender;
	private final int SENDER_REPEAT_INTERVAL = 300;
	private Handler mSenderHandler = new Handler();

	private Runnable mAutoPlayer;
	private final int AUTOPLAYER_REPEAT_INTERVAL = 300;
	private Handler mAutoPlayerHandler = new Handler();

	Drawable mFocusedTabImage;
	Drawable mNormalTabImage;

	public DreamWaverStore mDBStore;

	class RecordItem {
		int channel;
		int interval;	// pulse interval
		long timepos;

		RecordItem() {
			channel = 0;
			interval = 1;
			timepos = 0;
		}

		RecordItem(RecordItem a) {
			channel = a.channel;
			interval = a.interval;
			timepos = a.timepos;
		}

		RecordItem(int c, int afreq, long atimepos) {
			channel = c;
			interval = afreq;
			timepos = atimepos;
		}
	}

	class DataFile {
		public DataFile() {

		}

		public void write(String fpath, List<RecordItem> data) {
			Log.v("writeString", "start");
			try {
				FileOutputStream fileOutputStream = openFileOutput(fpath,
						MODE_PRIVATE);
				String writeString;
				for (Iterator<RecordItem> it = data.iterator(); it.hasNext();) {
					RecordItem item = it.next();
					fileOutputStream.write(Integer.toString(item.channel)
							.getBytes());
					writeString = ",";
					fileOutputStream.write(writeString.getBytes());

					fileOutputStream.write(Integer.toString(item.interval)
							.getBytes());
					writeString = ",";
					fileOutputStream.write(writeString.getBytes());

					fileOutputStream.write(Long.toString(item.timepos)
							.getBytes());
					writeString = "\n";
					fileOutputStream.write(writeString.getBytes());
				}
				// writeString = "END;";
				// fileOutputStream.write(writeString.getBytes());
				fileOutputStream.close();
				Log.v("writeString", "end");
			} catch (FileNotFoundException e) {
				Log.v("writeString", "FileNotFoundException");
			} catch (IOException e) {
				Log.v("writeString", "IOException");
			}

		}

		public List<RecordItem> read(String fpath) {
			Log.v("readString", "start");
			List<RecordItem> list = new LinkedList<RecordItem>();
			try {
				FileInputStream fileInputStream;
				fileInputStream = openFileInput(fpath);
				byte[] readBytes = new byte[fileInputStream.available()];
				fileInputStream.read(readBytes);
				String readString = new String(readBytes);
				StringTokenizer lnst = new StringTokenizer(readString, "\n");
				while (lnst.hasMoreTokens()) {
					String line = lnst.nextToken();
					Log.v("readString line ", line);
					RecordItem data = new RecordItem();
					StringTokenizer st = new StringTokenizer(line, ",");
					if (!st.hasMoreTokens()) {
						break; // error
					}
					data.channel = Integer.parseInt(st.nextToken());
					if (!st.hasMoreTokens()) {
						break; // error
					}
					data.interval = Integer.parseInt(st.nextToken());
					if (!st.hasMoreTokens()) {
						break; // error
					}
					data.timepos = Long.parseLong(st.nextToken());
					list.add(data);
				}
				fileInputStream.close();
				Log.v("readString", "end");
			} catch (FileNotFoundException e) {
				Log.v("readString", "FileNotFoundException");
			} catch (IOException e) {
				Log.v("readString", "IOException");
			}
			return list;
		}
	}

	class Player {
		List<RecordItem> mLists;
		Iterator<RecordItem> it;
		RecordItem item;
		long startTimeMillis = 0;
		DreamWaverStoreData mStoreData;

		void setStoreData(DreamWaverStoreData data) {
			mStoreData = data;
		}

		public void start() {
			if (mAutoPlayer == null) {
				Log.v("Player start", "start");
				if (mStoreData != null) {
					Log.v("Player start", mStoreData.filepath);
					DataFile datafile = new DataFile();
					mLists = datafile.read(mStoreData.filepath);
					it = mLists.iterator();
					makeChangeToAutoplay();
					startTimeMillis = System.currentTimeMillis();
					if (it.hasNext()) {
						item = it.next();
					} else {
						item = null;
					}
					mAutoPlayer = new Runnable() {
						public void run() {
							long currenttime = System.currentTimeMillis()
									- startTimeMillis;
							while (item != null) {
								if (item.timepos < currenttime) {
									makeFreqCommand(item.channel, item.interval, 0);
									mPlayerController.setFreqSliderPosition(
											item.channel, item.interval);
									if (it.hasNext()) {
										item = it.next();
									} else {
										item = null;
									}
								} else {
									break;
								}
							}
							if (item == null && !it.hasNext()) { // loop
								startTimeMillis = System.currentTimeMillis();
								it = mLists.iterator();
								if (it.hasNext()) {
									item = it.next();
								} else {
									item = null;
								}
							}

							mAutoPlayerHandler.postDelayed(this,
									AUTOPLAYER_REPEAT_INTERVAL);
						}
					};
					mAutoPlayerHandler.postDelayed(mAutoPlayer,
							AUTOPLAYER_REPEAT_INTERVAL);
				}
			}
			Log.v("Player start", "end");
		}

		public void stop() {
			if (mAutoPlayer != null) {
				mAutoPlayerHandler.removeCallbacks(mAutoPlayer);
				mAutoPlayer = null;
				makeChangeToStop();
			}
		}
	}

	class Recorder {
		// List<Item>[] mLists;
		List<RecordItem> mLists;
		long startTimeMillis = 0;
		boolean recording = false;
		boolean recorded = false;

		public Recorder() {
			mLists = new LinkedList<RecordItem>();

		}

		public boolean isRecording() {
			return recording;
		}

		public void start() {
			if (!recording) {
				mLists = new LinkedList<RecordItem>();
				recording = true;
				startTimeMillis = System.currentTimeMillis();
			}
		}

		public void stop() {
			if (recording == true) {
				recorded = true;
			}else{
				recorded = false;
			}
			recording = false;
		}

		public void add(int c, int freq) {
			if (recording) {
				long currentTimeMillis = System.currentTimeMillis();
				RecordItem rec = new RecordItem(c, freq, currentTimeMillis
						- startTimeMillis);
				mLists.add(rec);
			}
		}

		public void dump() {

		}

		public void save() {
			if (recorded) {
				DreamWaverStoreData newdata = new DreamWaverStoreData();
				Date date = new Date();
				newdata.title = date.toLocaleString();
				newdata.date = date.toGMTString();
				newdata.filepath = "DW" + System.currentTimeMillis() + ".txt";

				Log.d(TAG, "save " + newdata.title + newdata.date
						+ newdata.filepath);
				// data file
				DataFile file = new DataFile();
				file.write(newdata.filepath, mLists);
				// DB
				mDBStore.open();
				mDBStore.add(newdata);
				mDBStore.close();
				
				mLists.clear();
				mLists = null;
			}
		}

	}

	Recorder mRecorder = null;
	Player mPlayer = null;

	public static final byte DWSELFCHECK = 0;
	public static final byte DWAUTOPLAY = 1;
	public static final byte MANUALPLAY = 2;
	public static final byte RECORDPALY = 3;
	public static final byte DWSTOP = 4;

	public static final byte DWTURNON = 0;
	public static final byte DWTURNOFF = 1;
	public static final byte DWCHANGEMODE = 2;
	public static final byte DWMUTE = 3;
	public static final byte DWUNMUTE = 4;
	public static final byte DWSETCHANNELFEREQ = 5;

	// private class Sender extends Object implements
	public class DreamWaverCommand {
		public DreamWaverCommand() {
			command = DWSELFCHECK;
			buffer = null;
		}

		public byte command;
		public byte[] buffer;

		public DreamWaverCommand makeMuteCommand() {
			command = DWMUTE;
			buffer = null;
			return this;
		}

		public DreamWaverCommand makeUnmuteCommand() {
			command = DWUNMUTE;
			buffer = null;
			return this;
		}

		public DreamWaverCommand makeChangeToSelfcheck() {
			command = DWCHANGEMODE;
			buffer = new byte[1];
			buffer[0] = DWSELFCHECK;
			return this;
		}

		public DreamWaverCommand makeChangeToAutoplay() {
			command = DWCHANGEMODE;
			buffer = new byte[1];
			buffer[0] = DWAUTOPLAY;
			return this;
		}

		public DreamWaverCommand makeChangeToManualplay() {
			command = DWCHANGEMODE;
			buffer = new byte[1];
			buffer[0] = MANUALPLAY;
			return this;
		}

		public DreamWaverCommand makeChangeToRecordeplay() {
			command = DWCHANGEMODE;
			buffer = new byte[1];
			buffer[0] = RECORDPALY;
			return this;
		}

		public DreamWaverCommand makeChangeToStop() {
			command = DWCHANGEMODE;
			buffer = new byte[1];
			buffer[0] = DWSTOP;
			return this;
		}

		public DreamWaverCommand makeFreqCommand(int c, int interval, long duration) {
			command = DWSETCHANNELFEREQ;
			buffer = new byte[7];
			buffer[0] = (byte) (c + 2); // channel
			buffer[1] = (byte) (interval >> 8);
			buffer[2] = (byte) (interval % 256);
			buffer[3] = (byte) (duration >> 24);
			buffer[4] = (byte) ((duration >> 16) % 256);
			buffer[5] = (byte) ((duration >> 8) % 256);
			buffer[6] = (byte) (duration % 256);

			return this;
		}

	}

	private static Queue<DreamWaverCommand> mQueue = null;

	private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (ACTION_USB_PERMISSION.equals(action)) {
				synchronized (this) {
					UsbAccessory accessory = UsbManager.getAccessory(intent);
					if (intent.getBooleanExtra(
							UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
						openAccessory(accessory);
						Log.d(TAG, "UsbReceiver openAccessory" + accessory);
					} else {
						Log.d(TAG, "permission denied for accessory "
								+ accessory);
					}
					mPermissionRequestPending = false;
				}
			} else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
				UsbAccessory accessory = UsbManager.getAccessory(intent);
				if (accessory != null && accessory.equals(mAccessory)) {
					Log.d(TAG, "UsbReceiver closeAccessory" + accessory);
					closeAccessory();
				}
			}
		}
	};

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.d(TAG, "onCreate");
		mFocusedTabImage = getResources().getDrawable(
				R.drawable.tab_focused_holo_dark);
		mNormalTabImage = getResources().getDrawable(
				R.drawable.tab_normal_holo_dark);

		mUsbManager = UsbManager.getInstance(this);
		mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
				ACTION_USB_PERMISSION), 0);
		IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
		filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
		registerReceiver(mUsbReceiver, filter);

		if (getLastNonConfigurationInstance() != null) {
			mAccessory = (UsbAccessory) getLastNonConfigurationInstance();
			openAccessory(mAccessory);
		}

		setContentView(R.layout.main);
		enableControls(false);

		if (mAccessory != null) {
			showControls();
		} else {
			hideControls();
		}
	}

	@Override
	public Object onRetainNonConfigurationInstance() {
		if (mAccessory != null) {
			return mAccessory;
		} else {
			return super.onRetainNonConfigurationInstance();
		}
	}

	@Override
	public void onResume() {
		Log.d(TAG, "onResume");
		super.onResume();

		Intent intent = getIntent();
		if (mInputStream != null && mOutputStream != null) {
			Log.d(TAG, "onResume" + mInputStream + mOutputStream);
			return;
		}

		UsbAccessory[] accessories = mUsbManager.getAccessoryList();
		UsbAccessory accessory = (accessories == null ? null : accessories[0]);
		if (accessory != null) {
			if (mUsbManager.hasPermission(accessory)) {
				Log.d(TAG, "onResume openAccessory" + accessory);
				openAccessory(accessory);
			} else {
				synchronized (mUsbReceiver) {
					if (!mPermissionRequestPending) {
						mUsbManager.requestPermission(accessory,
								mPermissionIntent);
						mPermissionRequestPending = true;
					}
				}
			}
		} else {
			Log.d(TAG, "mAccessory is null");
		}
	}

	@Override
	public void onPause() {
		super.onPause();
		closeAccessory();
	}

	@Override
	public void onDestroy() {
		closeAccessory();
		unregisterReceiver(mUsbReceiver);
		super.onDestroy();
	}

	private void openAccessory(UsbAccessory accessory) {
		mFileDescriptor = mUsbManager.openAccessory(accessory);
		if (mFileDescriptor != null) {
			mAccessory = accessory;
			FileDescriptor fd = mFileDescriptor.getFileDescriptor();
			mInputStream = new FileInputStream(fd);
			if (mInputStream == null) {
				Log.d(TAG, "mInputStream not opened");
			}
			mOutputStream = new FileOutputStream(fd);
			if (mOutputStream == null) {
				Log.d(TAG, "mOutputStream not opened");
			}
			mQueue = new ConcurrentLinkedQueue<DreamWaverCommand>();

			Thread thread = new Thread(null, this, "DreamWaver");
			thread.start();

			mSender = new Runnable() {
				public void run() {
					while (!mQueue.isEmpty()) {
						sendCommand(mQueue.poll());
					}
					mSenderHandler.postDelayed(this, SENDER_REPEAT_INTERVAL);
				}
			};
			mSenderHandler.postDelayed(mSender, SENDER_REPEAT_INTERVAL);

			mRecorder = new Recorder();
			mPlayer = new Player();

			mDBStore = new DreamWaverStore(this);
			// DreamWaverStoreData data = new DreamWaverStoreData();
			// data.title = "sss";
			// data.date = "Date";
			// data.filepath ="ffff.txt";
			// mDBStore.open();
			// mDBStore.add(data);
			// mDBStore.close();

			Log.d(TAG, "accessory opened");
			enableControls(true);
		} else {
			Log.d(TAG, "accessory open fail");
		}
	}

	private void closeAccessory() {
		enableControls(false);

		try {
			if (mInputStream != null) {
				mInputStream.close();
			}
			if (mOutputStream != null) {
				mOutputStream.close();
			}
			if (mFileDescriptor != null) {
				mFileDescriptor.close();
			}
			mSenderHandler.removeCallbacks(mSender);
			stopRecord();
			stopPlayer();
		} catch (IOException e) {
		} finally {
			mFileDescriptor = null;
			mInputStream = null;
			mOutputStream = null;
			mAccessory = null;
			mRecorder = null;
			mPlayer = null;
			mDBStore = null;
		}
	}

	private int composeInt(byte hi, byte lo) {
		int val = (int) hi & 0xff;
		val *= 256;
		val += (int) lo & 0xff;
		return val;
	}

	public void run() {
		int ret = 0;
		byte[] buffer = new byte[16384];
		int i;
		int c;

		makeChangeToManualplay();
		for (c = 0; c < 12; c++) {
			makeFreqCommand(c, 80 + 20 * c, 0);
		}

		while (ret >= 0) {
			try {
				ret = mInputStream.read(buffer);
			} catch (IOException e) {
				break;
			}

			i = 0;
			while (i < ret) {
				int len = ret - i;

				switch (buffer[i]) {

				default:
					Log.d(TAG, "unknown msg: " + buffer[i]);
					i = len;
					break;
				}
			}/* */

		}
	}

	/*
	 * Handler mHandler = new Handler() {
	 * 
	 * @Override public void handleMessage(Message msg) { switch (msg.what) {
	 * case MESSAGE_SWITCH: SwitchMsg o = (SwitchMsg) msg.obj;
	 * handleSwitchMessage(o); break;
	 * 
	 * case MESSAGE_TEMPERATURE: TemperatureMsg t = (TemperatureMsg) msg.obj;
	 * handleTemperatureMessage(t); break;
	 * 
	 * case MESSAGE_LIGHT: LightMsg l = (LightMsg) msg.obj;
	 * handleLightMessage(l); break;
	 * 
	 * case MESSAGE_JOY: JoyMsg j = (JoyMsg) msg.obj; handleJoyMessage(j);
	 * break;
	 * 
	 * default: break; } } };
	 */
	public DreamWaverCommand makeMuteCommand() {
		DreamWaverCommand comamnd = new DreamWaverCommand();
		comamnd.makeMuteCommand();
		mQueue.add(comamnd);
		return comamnd;
	}

	public DreamWaverCommand makeUnmuteCommand() {
		DreamWaverCommand comamnd = new DreamWaverCommand();
		comamnd.makeUnmuteCommand();
		mQueue.add(comamnd);
		return comamnd;
	}

	public DreamWaverCommand makeChangeToSelfcheck() {
		DreamWaverCommand comamnd = new DreamWaverCommand();
		comamnd.makeChangeToSelfcheck();
		mQueue.add(comamnd);
		return comamnd;
	}

	public DreamWaverCommand makeChangeToAutoplay() {
		DreamWaverCommand comamnd = new DreamWaverCommand();
		comamnd.makeChangeToAutoplay();
		mQueue.add(comamnd);
		return comamnd;
	}

	public DreamWaverCommand makeChangeToManualplay() {
		DreamWaverCommand comamnd = new DreamWaverCommand();
		comamnd.makeChangeToManualplay();
		mQueue.add(comamnd);
		return comamnd;
	}

	public DreamWaverCommand makeChangeToRecordeplay() {
		DreamWaverCommand comamnd = new DreamWaverCommand();
		comamnd.makeChangeToRecordeplay();
		mQueue.add(comamnd);
		return comamnd;
	}

	public DreamWaverCommand makeChangeToStop() {
		DreamWaverCommand comamnd = new DreamWaverCommand();
		comamnd.makeChangeToStop();
		mQueue.add(comamnd);
		return comamnd;
	}

	public DreamWaverCommand makeFreqCommand(int c, int interval, int duration) {
		DreamWaverCommand retcomamnd = new DreamWaverCommand();
		retcomamnd.makeFreqCommand(c, interval, duration);
		mQueue.add(retcomamnd);
		mRecorder.add(c, interval);
		return retcomamnd;
	}

	public void sendCommand(DreamWaverCommand command) {
		if (mOutputStream != null) {
			try {
				mOutputStream.write(command.command);
				if (command.buffer != null) {
					mOutputStream.write(command.buffer);
				}
			} catch (IOException e) {
				Log.e(TAG, "write failed", e);
			}
		}
	}

	// tabs
	TextView mAutoLabel;
	TextView mManualLabel;
	TextView mSelfcheckLabel;

	LinearLayout mAutoContainer;
	LinearLayout mManualContainer;
	LinearLayout mSelfcheckContainer;
	LinearLayout mPlayerContainer;
	int currentTab = -1;

	public void onClick(View v) {
		int vId = v.getId();
		switch (vId) {
		case R.id.autoLabel:
			showTabContents(0);
			break;
		case R.id.manualLabel:
			showTabContents(1);
			break;
		case R.id.selfcheckLabel:
			showTabContents(2);
			break;
		}
	}

	void showTabContents(int selectTab) {
		if (currentTab == selectTab) {
			return;
		}
		makeChangeToStop();
		switch (selectTab) {
		case 0:
			mAutoContainer.setVisibility(View.VISIBLE);
			mAutoLabel.setBackgroundDrawable(mFocusedTabImage);
			mManualContainer.setVisibility(View.GONE);
			mManualLabel.setBackgroundDrawable(mNormalTabImage);
			mSelfcheckContainer.setVisibility(View.GONE);
			mSelfcheckLabel.setBackgroundDrawable(mNormalTabImage);
			mPlayerContainer.setVisibility(View.GONE);

			mAutoController.resetControls();
			mManualController.resetControls();
			mSelfcheckController.resetControls();
			mPlayerController.resetControls();
			currentTab = 0;
			break;
		case 1:
			mAutoContainer.setVisibility(View.GONE);
			mAutoLabel.setBackgroundDrawable(mNormalTabImage);
			mManualContainer.setVisibility(View.VISIBLE);
			mManualLabel.setBackgroundDrawable(mFocusedTabImage);
			mSelfcheckContainer.setVisibility(View.GONE);
			mSelfcheckLabel.setBackgroundDrawable(mNormalTabImage);
			mPlayerContainer.setVisibility(View.GONE);

			mAutoController.resetControls();
			mManualController.resetControls();
			mSelfcheckController.resetControls();
			mPlayerController.resetControls();
			mManualController.sendAllFreq();
			currentTab = 1;
			break;
		case 2:
			mAutoContainer.setVisibility(View.GONE);
			mAutoLabel.setBackgroundDrawable(mNormalTabImage);
			mManualContainer.setVisibility(View.GONE);
			mManualLabel.setBackgroundDrawable(mNormalTabImage);
			mSelfcheckContainer.setVisibility(View.VISIBLE);
			mSelfcheckLabel.setBackgroundDrawable(mFocusedTabImage);
			mPlayerContainer.setVisibility(View.GONE);

			mAutoController.resetControls();
			mManualController.resetControls();
			mSelfcheckController.resetControls();
			mPlayerController.resetControls();

			currentTab = 2;
			break;
		case 3:
			mAutoContainer.setVisibility(View.GONE);
			mAutoLabel.setBackgroundDrawable(mFocusedTabImage);
			mManualContainer.setVisibility(View.GONE);
			mManualLabel.setBackgroundDrawable(mNormalTabImage);
			mSelfcheckContainer.setVisibility(View.GONE);
			mSelfcheckLabel.setBackgroundDrawable(mNormalTabImage);
			mPlayerContainer.setVisibility(View.VISIBLE);

			mAutoController.resetControls();
			mManualController.resetControls();
			mSelfcheckController.resetControls();
			mPlayerController.resetControls();
			currentTab = 3;
			break;
		}
	}

	// controls
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			Log.i(TAG, "BACK");
			if (currentTab == 3) {
				showTabContents(0);
				return false;
			} else {
				return super.onKeyDown(keyCode, event);
			}
		} else {
			return super.onKeyDown(keyCode, event);
		}
	}

	protected void enableControls(boolean enable) {
		if (enable) {
			showControls();
		} else {
			hideControls();
		}
	}

	protected void hideControls() {
		Log.d(TAG, "hideControls");
		setContentView(R.layout.no_device);
		mAutoController = null;
		mManualController = null;
		mSelfcheckController = null;
		mPlayerController = null;
		currentTab = -1;
	}

	protected void showControls() {
		Log.d(TAG, "showControls");
		setContentView(R.layout.main);

		mAutoController = new AutoController(this, false);
		mAutoController.accessoryAttached();
		mManualController = new ManualController(this, false);
		mManualController.accessoryAttached();
		mSelfcheckController = new SelfcheckController(this, false);
		mSelfcheckController.accessoryAttached();
		mPlayerController = new PlayerController(this, false);
		mPlayerController.accessoryAttached();

		mAutoContainer = (LinearLayout) findViewById(R.id.autoContainer);
		mManualContainer = (LinearLayout) findViewById(R.id.manualContainer);
		mSelfcheckContainer = (LinearLayout) findViewById(R.id.selfcheckContainer);
		mPlayerContainer = (LinearLayout) findViewById(R.id.playerContainer);

		mAutoLabel = (TextView) findViewById(R.id.autoLabel);
		mManualLabel = (TextView) findViewById(R.id.manualLabel);
		mSelfcheckLabel = (TextView) findViewById(R.id.selfcheckLabel);

		mAutoLabel.setOnClickListener(this);
		mManualLabel.setOnClickListener(this);
		mSelfcheckLabel.setOnClickListener(this);

		showTabContents(0);
	}

	// recording
	public void startRecord() {
		if (mRecorder != null && !mRecorder.isRecording()) {
			mRecorder.start();
			mManualController.sendAllFreq();
		}
	}

	public void stopRecord() {

		if (mRecorder != null && mRecorder.isRecording()) {
			mRecorder.stop();
			// save
			AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
					this);
			// alertDialogBuilder.setTitle("Save");
			// alertDialogBuilder.setMessage("Save");
			alertDialogBuilder.setPositiveButton("Save",
					new DialogInterface.OnClickListener() {
						// @Override
						public void onClick(DialogInterface dialog, int which) {

							mRecorder.save();
						}
					});
			alertDialogBuilder.setNegativeButton("Cancel",
					new DialogInterface.OnClickListener() {
						// @Override
						public void onClick(DialogInterface dialog, int which) {
						}
					});
			alertDialogBuilder.setCancelable(true);
			AlertDialog alertDialog = alertDialogBuilder.create();
			alertDialog.show();
		}
	}

	// player
	public void startPlayer() {
		if (mPlayer != null) {
			mPlayer.start();
		}
	}

	public void stopPlayer() {
		if (mPlayer != null) {
			mPlayer.stop();
		}

	}
}